package user

import (
	"code/token"
	"database/sql"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	_ "github.com/go-sql-driver/mysql"
)

type Info struct {
	AvatarUrl string `json:"avatarUrl"`
	NickName  string `json:"nickName"`
	Grade     int64  `json:"grade"`
	GradeType string `json:"gradeType"`
	Score     int64  `json:"score"`
}

type Date struct {
	UserInfo *Info `json:"userInfo"`
}

type Response struct {
	Code     int64  `json:"code"`
	Message  string `json:"message"`
	Type     string `json:"type"`
	UserInfo *Info  `json:"userInfo"`
}

var db *sql.DB

/* 初始化数据库的函数 */
func initDB() (err error) {
	// 连接数据库
	db, err = sql.Open("mysql", "wxappAdmin:wxappadmin1234@tcp(47.107.122.89:3306)/wxapp")
	if err != nil {
		return err
	}

	// 尝试与数据库建立连接
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil
}

/* 输入openid进行单行查询 */
func usermodelQueryRow(openid string) (i *Info, err error) {
	i = &Info{}

	// 执行sql语句
	s := fmt.Sprintf("SELECT avatarurl,nickname,grade,gradetype,score FROM usermodel WHERE openid='%s'", openid)
	err = db.QueryRow(s).Scan(&i.AvatarUrl, &i.NickName, &i.Grade, &i.GradeType, &i.Score)
	return
}

/* 插入数据 */
func usermodelInsertRow(openid string, date *Info) (err error) {
	s := fmt.Sprintf("INSERT INTO usermodel(openid,avatarurl,nickname,grade,gradetype,score) VALUES('%s','%s','%s','%d','%s','%d')", openid, date.AvatarUrl, date.NickName, 0, "初出茅庐", 0)
	_, err = db.Exec(s)
	return
}

/* 更新数据 */
func usermodelUpdateRow(openid string, date *Info) (err error) {
	s := fmt.Sprintf("UPDATE usermodel SET avatarurl='%s',nickname='%s' WHERE openid='%s'", date.AvatarUrl, date.NickName, openid)
	_, err = db.Exec(s)
	return
}

/* 用户登录成功后将数据发到后端存入数据库并返回用户数据，如何数据已存在，则返回用户数据*/
func UserInfo(w http.ResponseWriter, r *http.Request) {
	// 判断是否为POST请求
	if r.Method != "POST" {
		w.Write([]byte("请使用POST请求！"))
		return
	}

	resp := Response{
		Code:    0,
		Message: "成功",
		Type:    "success",
		UserInfo: &Info{
			AvatarUrl: "",
			NickName:  "",
			Grade:     0,
			GradeType: "初出茅庐",
			Score:     0,
		},
	}

	// 获取token，并判断是否为有效token
	t := r.Header.Get("Authorization")
	u, err := token.ParseToken(t)
	if err != nil {
		resp.Code = 400
		resp.Message = err.Error()
		resp.Type = "error"

		// 传换成json格式返回
		result, _ := json.Marshal(resp)
		w.Header().Set("Content-Type", "application/json")
		w.Write(result)
		return
	}

	// 获取Post过来的数据
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		resp.Code = 400
		resp.Message = err.Error()
		resp.Type = "error"

		// 传换成json格式返回
		result, _ := json.Marshal(resp)
		w.Header().Set("Content-Type", "application/json")
		w.Write(result)
		return
	}
	defer r.Body.Close()

	// 解析post过来的数据成json格式
	date := Date{
		UserInfo: &Info{
			AvatarUrl: "",
			NickName:  "",
			Grade:     0,
			GradeType: "初出茅庐",
			Score:     0,
		},
	}
	json.Unmarshal([]byte(body), &date)

	// 连接数据库判断该用户是否存在，
	// 如果存在则将该用户的微信头像及昵称给替换成最新的，不存在则创建新用户
	initDB()
	res1, err := usermodelQueryRow(u.Openid)

	switch {
	case err == sql.ErrNoRows:
		// 该用户不存在
		err := usermodelInsertRow(u.Openid, date.UserInfo)
		if err != nil {
			resp.Code = 400
			resp.Message = err.Error()
			resp.Type = "error"

			// 传换成json格式返回
			result, _ := json.Marshal(resp)
			w.Header().Set("Content-Type", "application/json")
			w.Write(result)
			return
		}
		resp.UserInfo.AvatarUrl = date.UserInfo.AvatarUrl
		resp.UserInfo.NickName = date.UserInfo.NickName
		resp.UserInfo.Grade = 0
		resp.UserInfo.GradeType = "初出茅庐"
		resp.UserInfo.Score = 0
	case err != nil:
		resp.Code = 400
		resp.Message = err.Error()
		resp.Type = "error"

		// 传换成json格式返回
		result, _ := json.Marshal(resp)
		w.Header().Set("Content-Type", "application/json")
		w.Write(result)
		return
	default:
		// 该用户存在则修改昵称和头像
		err := usermodelUpdateRow("1", date.UserInfo)
		if err != nil {
			resp.Code = 401
			resp.Message = err.Error()
			resp.Type = "error"

			// 传换成json格式返回
			result, _ := json.Marshal(resp)
			w.Header().Set("Content-Type", "application/json")
			w.Write(result)
			return
		}
		resp.UserInfo.AvatarUrl = date.UserInfo.AvatarUrl
		resp.UserInfo.NickName = date.UserInfo.NickName
		resp.UserInfo.Grade = res1.Grade
		resp.UserInfo.GradeType = res1.GradeType
		resp.UserInfo.Score = res1.Score
	}

	// 传换成json格式返回
	result, _ := json.Marshal(resp)
	w.Header().Set("Content-Type", "application/json")
	w.Write(result)
	return
}
